package com.lsa.letcode.the81.searchInRotatedArrDupl;

import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.Test;

import com.lsa.helpers.Utils;

public class SearchInRotatedArrDuplTest {
	
	private static final boolean IS_DEBUG_PRINT = false;

	@Test
	public void test() {
		test(new int[] { 1, 1 }, 0 , -1);
		test(new int[] { 1, 1 }, 1);
		testByCyclicShift(new int[] { 1, 1, 1, 1, 1, 1, 3 }, 3);
		testByCyclicShift(new int[] { 1, 1, 2, 2, 3, 3 }, 3);
		testByCyclicShift(new int[] { 1, 1, 1, 3, 3, 3 }, 3);
		testByCyclicShift(new int[] { 3, 4, 4, 4, 5, 5, 1, 1, 2, 2 }, 3);
		testByCyclicShift(new int[] { 1, 1, 1, 3 }, 3);
		
		test(new int[] { 1, 1, 1, 1, 1, 1, 3 }, 3 , 6);
		test(new int[] { 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1 }, 3 , 6);
		
		test(new int[] { 3, 1 }, 1 , 1);
		test(new int[] { 1 }, 2 , -1);
		test(new int[] { 1 }, 1 , 0);
		test(new int[] {  }, 1 , -1);
		test(new int[] { 1, 2, 3, 4, 5, 6, 7, }, 3, 2);
		test(new int[] { 1, 2, 3, 4, 5, 6, 7, }, 8, -1);
		test(new int[] { 6, 1, 2, 3, 4, 5 }, 3, 3);
		test(new int[] { 6, 7, 1, 2, 3, 4, 5 }, 3, 4);
		test(new int[] { 5, 6, 7, 1, 2, 3, 4 }, 3, 5);
		test(new int[] { 4, 5, 6, 7, 1, 2, 3 }, 3, 6);
		test(new int[] { 3, 4, 5, 6, 7, 1, 2 }, 3, 0);
		test(new int[] { 2, 3, 4, 5, 6, 7, 1 }, 3, 1);
		//               0  1  2  3  4  5  6
		
		test(new int[] { 3, 1, 1, 1, 1, 1 }, 1 , 3);
		
	}
	
	private void test(int[] arr, int t, int expectedIdx) {
		Solution s = new Solution();
		int idx = s.searchIdx(arr, t);
		assertEquals(expectedIdx, idx);
	}
	
	private void testByCyclicShift(int[] arr, int t) {
		int[] c = arr;
		int[] first = Arrays.copyOf(arr, c.length);
		do{
			test(c,
					t);
			if (IS_DEBUG_PRINT) {System.out.println(Arrays.toString(c));}
			Utils.cyclicShiftRight(c);
		}
		while(!Arrays.equals(first, c));
	}
	
	private void test(int[] arr, int t) {
		Solution s = new Solution();
		int idx = s.searchIdx(arr, t);
		assertTrue(idx > -1);
		if (IS_DEBUG_PRINT){System.out.print(idx);}
		assertTrue(arr[idx] == t);
	}
}
